package fetcher

import (
	"context"
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/mmcdole/gofeed"
	"github.com/yourusername/rss-reader-ai/internal/model"
)

// =====================================================
// Fetcher - RSS/Atom 抓取器
// =====================================================

// Fetcher RSS 抓取器接口
type Fetcher interface {
	// FetchFeed 抓取指定 URL 的 RSS/Atom 内容
	FetchFeed(feedURL string) (*FeedData, error)
}

// FeedData 抓取的订阅源数据
type FeedData struct {
	Title       string        // 订阅源标题
	Description string        // 订阅源描述
	SiteURL     string        // 网站 URL
	IconURL     string        // 图标 URL
	Articles    []*ArticleData // 文章列表
}

// ArticleData 抓取的文章数据
type ArticleData struct {
	GUID        string    // 全局唯一标识符
	Title       string    // 标题
	Link        string    // 链接
	Description string    // 描述/摘要
	Content     string    // 完整内容
	Author      string    // 作者
	PublishedAt time.Time // 发布时间
	UpdatedAt   time.Time // 更新时间
}

// =====================================================
// rssFetcher - RSS 抓取器实现
// =====================================================

// rssFetcher 默认的 RSS 抓取器实现
type rssFetcher struct {
	parser     *gofeed.Parser
	timeout    time.Duration
	userAgent  string
}

// NewFetcher 创建 RSS 抓取器
// 参数:
//   - timeout: 抓取超时时间
//   - userAgent: User-Agent 标识
func NewFetcher(timeout time.Duration, userAgent string) Fetcher {
	return &rssFetcher{
		parser:    gofeed.NewParser(),
		timeout:   timeout,
		userAgent: userAgent,
	}
}

// =====================================================
// FetchFeed - 抓取订阅源
// =====================================================

// FetchFeed 抓取指定 URL 的 RSS/Atom 内容
func (f *rssFetcher) FetchFeed(feedURL string) (*FeedData, error) {
	// 1. 创建带超时的 Context
	ctx, cancel := context.WithTimeout(context.Background(), f.timeout)
	defer cancel()

	// 2. 解析 RSS/Atom
	log.Printf("📡 开始抓取: %s", feedURL)
	feed, err := f.parser.ParseURLWithContext(feedURL, ctx)
	if err != nil {
		return nil, fmt.Errorf("解析 RSS 失败: %w", err)
	}

	// 3. 提取订阅源信息
	feedData := &FeedData{
		Title:       feed.Title,
		Description: feed.Description,
		SiteURL:     feed.Link,
		Articles:    make([]*ArticleData, 0, len(feed.Items)),
	}

	// 4. 尝试获取图标
	if feed.Image != nil {
		feedData.IconURL = feed.Image.URL
	}

	// 5. 提取文章列表
	for _, item := range feed.Items {
		article := f.parseItem(item)
		if article != nil {
			feedData.Articles = append(feedData.Articles, article)
		}
	}

	log.Printf("✅ 抓取成功: %s, 文章数: %d", feed.Title, len(feedData.Articles))
	return feedData, nil
}

// =====================================================
// parseItem - 解析单个文章
// =====================================================

// parseItem 解析 RSS/Atom 条目为文章数据
func (f *rssFetcher) parseItem(item *gofeed.Item) *ArticleData {
	if item == nil {
		return nil
	}

	// 1. 提取 GUID (全局唯一标识符)
	guid := item.GUID
	if guid == "" {
		// 如果没有 GUID，使用 Link 作为唯一标识
		guid = item.Link
	}

	// 2. 提取标题
	title := strings.TrimSpace(item.Title)
	if title == "" {
		// 标题为空，跳过这篇文章
		return nil
	}

	// 3. 提取链接
	link := item.Link
	if link == "" {
		// 没有链接，使用 GUID
		link = guid
	}

	// 4. 提取描述和内容
	description := strings.TrimSpace(item.Description)
	content := strings.TrimSpace(item.Content)

	// 如果没有 content，使用 description
	if content == "" {
		content = description
	}

	// 如果没有 description，从 content 截取前 200 字符
	if description == "" && len(content) > 200 {
		description = content[:200] + "..."
	}

	// 5. 提取作者
	author := ""
	if item.Author != nil {
		author = item.Author.Name
	}
	// 兼容其他格式
	if author == "" && len(item.Authors) > 0 {
		author = item.Authors[0].Name
	}

	// 6. 提取发布时间
	publishedAt := time.Now()
	if item.PublishedParsed != nil {
		publishedAt = *item.PublishedParsed
	}

	// 7. 提取更新时间
	updatedAt := publishedAt
	if item.UpdatedParsed != nil {
		updatedAt = *item.UpdatedParsed
	}

	return &ArticleData{
		GUID:        guid,
		Title:       title,
		Link:        link,
		Description: description,
		Content:     content,
		Author:      author,
		PublishedAt: publishedAt,
		UpdatedAt:   updatedAt,
	}
}

// =====================================================
// ToArticle - 转换为 Article 模型
// =====================================================

// ToArticle 将 ArticleData 转换为 model.Article
func (a *ArticleData) ToArticle(feedID int64) *model.Article {
	return &model.Article{
		FeedID:      feedID,
		GUID:        a.GUID,
		Title:       a.Title,
		Link:        a.Link,
		Description: a.Description,
		Content:     a.Content,
		Author:      a.Author,
		PublishedAt: &a.PublishedAt, // 转为指针
		IsRead:      false,
		IsStarred:   false, // 修正字段名
	}
}
